/*******************************************************************************
 *
 *    Copyright (c) BaiNa Co. Ltd
 *
 *    LaputaBookReaderIIIRelease
 *
 *
 *    @author: DanLiu
 *    @since:  2009-12-25
 *    @version: 1.0
 *
 ******************************************************************************/

package small.hero.pageview;


import small.hero.pageview.ScrollablePageContainer.Vector;
import android.graphics.PointF;


/**
 *
 */
public class MyMath {

    /**
     * 已知两直线距离以及其中一条直线的截距求另一条直线的截距。
     *
     * @param distance
     *            两直线距离。
     * @param otherIcpt
     *            其中一条直线的截距。
     * @param k
     *            直线的斜率。
     * @return 所求直线的截距（所求直线在已知直线上侧）。
     */
    public static double calculateUperBwithDistanceAndAnotherB(double distance,
            double otherIcpt, double k) {
        if (k == Double.MAX_VALUE) {
            return otherIcpt - distance;
        }
        return otherIcpt + distance * Math.sqrt(1 + Math.pow(k, 2));
    }

    /**
     * 已知两直线距离以及其中一条直线的截距求另一条直线的截距。
     *
     * @param distance
     *            两直线距离。
     * @param otherIcpt
     *            其中一条直线的截距。
     * @param k
     *            直线的斜率。
     * @return 所求直线的截距（所求直线在已知直线下侧）。
     */
    public static double calculateLowerBwithDistanceAndAnotherB(
            double distance, double otherIcpt, double k) {
        if (k == Double.MAX_VALUE) {
            return otherIcpt + distance;
        }
        return otherIcpt - distance * Math.sqrt(1 + Math.pow(k, 2));
    }

    /**
     * 计算两直线的交点，需要保证的是k1,k2不等。
     *
     * @param k1
     *            直线1的斜率
     * @param b1
     *            直线1的截距
     * @param k2
     *            直线2的斜率
     * @param b2
     *            直线2的截距
     * @param intersectionP
     *            用于保存交点的坐标，不能为空。
     */
    public static void calculateIntersection(double k1, double b1, double k2,
            double b2, PointF intersectionP) {
        if (k1 == k2) {
            return;
        }
        if (k1 == Double.MAX_VALUE) {
            intersectionP.x = (float) b1;
            intersectionP.y = (float) (k2 * intersectionP.x + b2);
        } else if (k2 == Double.MAX_VALUE) {
            intersectionP.x = (float) b2;
            intersectionP.y = (float) (k1 * intersectionP.x + b1);
        } else {
            intersectionP.x = (float) ((b2 - b1) / (k1 - k2));
            intersectionP.y = (float) (k1 * intersectionP.x + b1);
        }
    }

    @SuppressWarnings("unused")
    private static boolean isNaN_kHappenned = false;

    /**
     * 计算两点连线的斜率。
     *
     * @param from
     *            起始点。
     * @param to
     *            终点。
     * @return 直线的斜率。
     */
    public static double calculateK(PointF from, PointF to) {
        if (from.x == to.x) {
            return Double.MAX_VALUE;
        }
        return (from.y - to.y) / (from.x - to.x);
    }

    /**
     * 计算两点连线的截距。
     *
     * @param from
     *            起始点。
     * @param to
     *            终点。
     * @return 连线的截距。如果为垂直于x轴的垂线，返回值为垂线的横坐标。
     */
    public static double calculateB(PointF from, PointF to) {
        final double k = calculateK(from, to);
        if (k == Double.MAX_VALUE) {
            return from.x;
        }
        return to.y - k * to.x;
    }

    /**
     * 利用向量的叉积计算向量vectorA到vectorB的夹角 p0 x p1 = |p0||p1|sin(p0^p1) = p0(x) *
     * p1(y) - p0(y) *p1(x)
     *
     * @return 向量夹角。
     */
    public static float calculateShadowRotateAngle(final Vector vectorA,
            final Vector vectorB, byte turnPageFrom) {
        final double lengthProduct =  Math.sqrt(Math.pow(vectorA.x, 2)
                + Math.pow(vectorA.y, 2))
                *  Math.sqrt(Math.pow(vectorB.x, 2)
                        + Math.pow(vectorB.y, 2));
        final double radian = Math
                .asin((vectorA.x * vectorB.y - vectorA.y * vectorB.x)
                        / lengthProduct);
        final float angle = (float) (radian * 180.0f / Math.PI);
        switch (turnPageFrom) {
        case ScrollablePageContainer.FROM_UP_RIGHT:
            return -angle;
        case ScrollablePageContainer.FROM_DOWN_RIGHT:
            return angle;
        case ScrollablePageContainer.FROM_UP_LEFT:
            return 180 - angle;
        case ScrollablePageContainer.FROM_DOWN_LEFT:
            return 180 + angle;
        }
        return angle;
    }

    /**
     * 计算两点间的距离
     *
     * @param from
     * @param to
     * @return
     */
    public static float calculatePointsDistant(PointF from, PointF to) {
        return (float) Math.sqrt(Math.pow(from.x - to.x, 2)
                + Math.pow(from.y - to.y, 2));
    }

}
